home *** CD-ROM | disk | FTP | other *** search
/ USA Bestseller / USA BESTSELLER Vol 1-95 (Hepp-Computer)(1995).iso / e079 / writepcx.c < prev    next >
C/C++ Source or Header  |  1993-03-21  |  23KB  |  474 lines

  1. /************************************************************************\
  2.  *                                                                      *
  3.  *  writepcx.c                                                          *
  4.  *                                                                      *
  5.  *  This file is part of PICTURE MAN image file converter/processor     *
  6.  *                                                                      *
  7.  *  1992 Potapov WORKS, STOIK Ltd.                                      *
  8.  *                                                                      *
  9.  *  This file contains source code for PCX file writer                  *
  10.  *                                                                      *
  11.  *  Compiler: MS C v.6.00A                                              *
  12.  *                                                                      *
  13.  *  You may use, modify and distribute this code freely                 *
  14.  *                                                                      *
  15. \************************************************************************/
  16. #include <windows.h>
  17. #include "custconv.h"
  18.   
  19. #define SEEK_SET    0
  20. #define SEEK_CUR    1
  21. #define SEEK_END    2
  22.   
  23. #define BUFSIZE 4096
  24.   
  25.  
  26. typedef struct {
  27.         char         manuf;     /* Always =10 for Paintbrush   */
  28.         char         hard;      /* Version information         */
  29.         char         encod;     /* Run-length encoding (=1)    */
  30.         char         bitpx;     /* Bits per pixel              */
  31.         unsigned     x1;        /* Picture dimensions (incl)   */
  32.         unsigned     y1;
  33.         unsigned     x2;
  34.         unsigned     y2;
  35.         unsigned     hres;      /* Display horiz resolution    */
  36.         unsigned     vres;      /* Display vert  resolution    */
  37.         char         clrma[48]; /* Pallete                     */
  38.         char         vmode;     /* (ignored)                   */
  39.         char         nplanes;   /* Number of planes (ver 2.5=0)*/
  40.         unsigned     bplin;     /* Bytes per line              */
  41.         unsigned     palinfo;   /* Palette Info (1=col, 2=gray)*/
  42.         unsigned     shres;     /* Scanner resolution          */
  43.         unsigned     svres;     /*                             */
  44.         char         xtra[54];  /* Extra space (filler)        */
  45.        } PCXhdr;
  46.  
  47.  
  48. typedef struct{
  49.                int file;
  50.                BOOL PCXpalette;
  51.                PAL pal;
  52.                BYTE buffer[BUFSIZE];
  53.                WORD pos;
  54.                     PCXhdr hdr;
  55.                   }PCXStruct;
  56.   
  57. /************************************************************************\
  58.  *                                                                      *
  59.  * ROUTINE: int FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg,       *
  60.  *                                 WORD cbHeapSize, LPSTR lpszCmdLine)  *
  61.  * PURPOSE: DLL entry point.                                            *
  62.  *                                                                      *
  63. \************************************************************************/
  64. int FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg,
  65. WORD cbHeapSize, LPSTR lpszCmdLine)
  66. {
  67.     return 1;
  68. }
  69.   
  70. /************************************************************************\
  71.  *                                                                      *
  72.  * ROUTINE: int FAR PASCAL WEP(int bSystemExit)                         *
  73.  *                                                                      *
  74.  * PURPOSE: DLL exit procedure                                          *
  75.  *                                                                      *
  76. \************************************************************************/
  77. int FAR PASCAL WEP(int bSystemExit)
  78. {
  79.     return 1;
  80. }
  81.   
  82.   
  83. /************************************************************************\
  84.  *                                                                      *
  85.  * ROUTINE: WORD FAR PASCAL Magic(void)                                 *
  86.  *                                                                      *
  87.  * PURPOSE: Identification routine                                      *
  88.  * RETURNS: 'Magic number' SRC_MAGIC                                    *
  89.  *                                                                      *
  90. \************************************************************************/
  91. WORD FAR PASCAL Magic(void)
  92. {
  93.     return DST_MAGIC;
  94. }
  95.   
  96. /************************************************************************\
  97.  *                                                                      *
  98.  * ROUTINE: void FAR PASCAL GetDescription(LPSTR str)                   *
  99.  *                                                                      *
  100.  * PURPOSE: Sets format name                                            *
  101.  *                                                                      *
  102.  * PARAMETERS: LPSTR str - pointer for format name storage. The length  *
  103.  *             name must be less than 40!                               *
  104.  *                                                                      *
  105. \************************************************************************/
  106. void FAR PASCAL GetDescription(LPSTR str)
  107. {
  108.     lstrcpy(str,"ZSoft PaintBrush PCX");
  109. }
  110.   
  111. /************************************************************************\
  112.  *                                                                      *
  113.  * ROUTINE: void FAR PASCAL GetExtension(LPSTR str)                     *
  114.  *                                                                      *
  115.  * PURPOSE: Sets format file extension                                  *
  116.  *                                                                      *
  117.  * PARAMETERS: LPSTR str - pointer for format file extension.           *
  118.  *                                                                      *
  119. \************************************************************************/
  120. void FAR PASCAL GetExtension(LPSTR str)
  121. {
  122.     lstrcpy(str,"PCX");
  123. }
  124.   
  125. /************************************************************************\
  126.  *                                                                      *
  127.  * ROUTINE: DWORD FAR PASCAL GetFlags(void)                             *
  128.  *                                                                      *
  129.  * PURPOSE: Sets flag for converter capabilities                        *
  130.  *                                                                      *
  131.  * PARAMETERS: None                                                     *
  132.  *                                                                      *
  133.  * RETURNS: Flags                                                       *
  134.  *  Color info bits                                                     *
  135.  *  INFO_COLOR      // Image is colored                                 *
  136.  *  INFO_PALETTE    // Image is paletted                                *
  137.  *  INFO_NEGATIVE   // Image is negative                                *
  138.  *  File organization bits                                              *
  139.  *  INFO_TEMPFILE   // Only using temporary file                        *
  140.  *  INFO_COMPRESSED // Image is compressed                              *
  141.  *  INFO_FORWARD    // Up to down                                       *
  142.  *  INFO_BACKWARD   // Down to up                                       *
  143.  *  INFO_RANDOM     // Random access is allowed                         *
  144.  *  Row organization bits                                               *
  145.  *  INFO_PACKED     // (bps < 8) bits are shifted together              *
  146.  *  INFO_SEPARATE   // (bps !=8) bitplanes are separated                *
  147.  *                                                                      *
  148.  *  Bits for GetFlags()                                                 *
  149.  *  Destination capabilites bits                                        *
  150.  *  INFO_1BPS       // Accepts 1-bit data                               *
  151.  *  INFO_4BPS       // Accepts 4-bit data                               *
  152.  *  INFO_8BPS       // Accepts 8-bit data                               *
  153.  *  INFO_24BPS      // Accepts 24-bit data                              *
  154.  *  INFO_GRAY       // Accepts true gray data                           *
  155.  *  INFO_STDPAL     // Requires std. EGA/VGA palette                    *
  156.  *  INFO_ANYPAL     // Accepts any palette                              *
  157.  *  Source/Destination capabilites bits                                 *
  158.  *  INFO_HASOPTIONS // Has SetOptions()                                 *
  159.  *  INFO_NOFILE     // Do not open src/dst file                         *
  160.  *                                                                      *
  161.  *  ALL OTHER BITS ARE RESERVED                                         *
  162.  *                                                                      *
  163. \************************************************************************/
  164. DWORD FAR PASCAL GetFlags(void)
  165. {
  166.     return ( INFO_COMPRESSED | INFO_FORWARD | INFO_1BPS | \
  167.     INFO_4BPS | INFO_8BPS | INFO_24BPS | INFO_STDPAL | INFO_ANYPAL );
  168. }
  169. /************************************************************************\
  170.  *                                                                      *
  171.  * ROUTINE: int FAR PASCAL GetPrivateSize()                             *
  172.  *                                                                      *
  173.  * PURPOSE: Returns size of private memory block                        *
  174.  *                                                                      *
  175.  *                                                                      *
  176. \************************************************************************/
  177. int FAR PASCAL GetPrivateSize()
  178. {
  179.    return sizeof(PCXStruct);
  180. }
  181.   
  182. /************************************************************************\
  183.  *                                                                      *
  184.  * ROUTINE: int   FAR PASCAL WriteHeader(LPINFO p, void far * lpPrivate)*
  185.  *                                                                      *
  186.  * PURPOSE: Writes image header.                                        *
  187.  *                                                                      *
  188.  * PARAMETERS: LPINFO p - pointer to INFO structure                     *
  189.  *             void far * lpPrivate - pointer to                        *
  190.  *             custom structure to store private data                   *
  191.  *                                                                      *
  192.  * RETURNS:                                                             *
  193.  * OK         - Success                                                 *
  194.  * BADFORMAT  - Bad signature                                           *
  195.  * UNSUPPORTED- Unsupported subformat                                   *
  196.  * BADFILE    - Error in file structure                                 *
  197.  * CANNOTOPEN - Cannot open src/dest                                    *
  198.  * INTERNAL   - Reserved                                                *
  199.  * BADDLL     - Error initializing DLL                                  *
  200.  * BADREQUEST - Unsupported type of conversion                          *
  201.  * BADTEMPFILE- Error creating/reading tempfile                         *
  202.  * NOMEMORY   - No enough global heap                                   *
  203.  * NODISK     - No enough disk space                                    *
  204.  * USERABORT  - Cancelled by user                                       *
  205.  * BADPARMS   - Conflicting parameters                                  *
  206.  *                                                                      *
  207. \************************************************************************/
  208. int   FAR PASCAL WriteHeader(LPINFO p, void far *lpPrivate)
  209. {
  210.     int i,j;
  211.      PCXStruct far * lpPCXStruct = lpPrivate;
  212.  
  213.  
  214.          lpPCXStruct->hdr.manuf = 10;   // manuf
  215.          lpPCXStruct->hdr.hard  = 5;    // hard
  216.          lpPCXStruct->hdr.encod = 1;    // encod
  217.          lpPCXStruct->hdr.bitpx = 1;    // bitpix ***
  218.          lpPCXStruct->hdr.x1    = 0;    // x1, y1
  219.          lpPCXStruct->hdr.y1    = 0;    
  220.          lpPCXStruct->hdr.x2    = 0;    
  221.          lpPCXStruct->hdr.y2    = 0;    
  222.          lpPCXStruct->hdr.hres  = 640 ;
  223.          lpPCXStruct->hdr.vres  = 480;  
  224.          lpPCXStruct->hdr.vmode = 0;     
  225.          lpPCXStruct->hdr.nplanes = 1;  
  226.          lpPCXStruct->hdr.bplin  = 0;   
  227.          lpPCXStruct->hdr.palinfo= 0;   
  228.          lpPCXStruct->hdr.shres = 300;  
  229.          lpPCXStruct->hdr.svres = 300;  
  230.   
  231.     lpPCXStruct->hdr.x2 = p->w - 1;
  232.     lpPCXStruct->hdr.y2 = p->h - 1;
  233.     if( p->resunit == RES_SCREEN )
  234.     {
  235.         lpPCXStruct->hdr.hres = (WORD)p->xres; lpPCXStruct->hdr.vres = (WORD)p->yres;
  236.     }
  237.     switch( p->bps )
  238.     {
  239.         case 1:
  240.             lpPCXStruct->hdr.bitpx = 1;
  241.             lpPCXStruct->hdr.nplanes = 1;
  242.             if( p->resunit != RES_SCREEN )
  243.             {
  244.                 lpPCXStruct->hdr.hres = 640; lpPCXStruct->hdr.vres = 480;
  245.             }
  246.             lpPCXStruct->PCXpalette = 0;
  247.             lpPCXStruct->hdr.clrma[0] = lpPCXStruct->hdr.clrma[1] = lpPCXStruct->hdr.clrma[2] = 0;
  248.             lpPCXStruct->hdr.clrma[3] = lpPCXStruct->hdr.clrma[4] = lpPCXStruct->hdr.clrma[5] = 0xFF;
  249.             break;
  250.   
  251.         case 4:
  252.             lpPCXStruct->hdr.bitpx = 1;
  253.             lpPCXStruct->hdr.nplanes = 4;
  254.             if( p->resunit != RES_SCREEN )
  255.             {
  256.                 lpPCXStruct->hdr.hres = 640; lpPCXStruct->hdr.vres = 480;
  257.             }
  258.             lpPCXStruct->PCXpalette = 0;
  259.             for( i = 0; i < 16; i++ )
  260.                 for( j = 0; j < 3; j++ )
  261.                     lpPCXStruct->hdr.clrma[i*3+j] = p->pal[j][i];
  262.             break;
  263.   
  264.         case 8:
  265.             lpPCXStruct->hdr.bitpx = 8;
  266.             lpPCXStruct->hdr.nplanes = 1;
  267.             if( p->resunit != RES_SCREEN )
  268.             {
  269.                 lpPCXStruct->hdr.hres = 320; lpPCXStruct->hdr.vres = 200;
  270.             }
  271.             lpPCXStruct->PCXpalette = 1;
  272.             for( i = 0; i < 3; i++ )
  273.                 for( j = 0; j < 256; j++ )
  274.                     lpPCXStruct->pal[i][j] = p->pal[i][j];
  275.                 break;
  276.         case 24:
  277.             lpPCXStruct->hdr.bitpx = 8;
  278.             lpPCXStruct->hdr.nplanes = 3;
  279.             if( p->resunit != RES_SCREEN )
  280.             {
  281.                 lpPCXStruct->hdr.hres = 640; lpPCXStruct->hdr.vres = 480;
  282.             }
  283.                 break;
  284.     }
  285.     lpPCXStruct->file = p->file;
  286.     p->nplanes = lpPCXStruct->hdr.nplanes;
  287.     p->bplin = lpPCXStruct->hdr.bplin =
  288.     (WORD)( ( (DWORD)lpPCXStruct->hdr.bitpx * (DWORD)p->w + 15lu ) / 16lu ) * 2;
  289.     p->flags |= INFO_COMPRESSED | INFO_FORWARD | INFO_1BPS | \
  290.     INFO_4BPS | INFO_8BPS | INFO_24BPS | INFO_STDPAL | INFO_ANYPAL | \
  291.      INFO_COLOR | INFO_PALETTE;
  292.     if( lpPCXStruct->hdr.bitpx != 8 )   p->flags |= INFO_PACKED;
  293.     if( lpPCXStruct->hdr.nplanes != 1 ) p->flags |= INFO_SEPARATE;
  294.   
  295.     lpPCXStruct->pos = 0;
  296.     if(_lwrite( lpPCXStruct->file,(LPSTR)&(lpPCXStruct->hdr),sizeof(lpPCXStruct->hdr)) != sizeof(lpPCXStruct->hdr)) return NODISK;
  297.     return OK;
  298. }
  299.   
  300. /************************************************************************/
  301. /************************************************************************/
  302. /************************************************************************/
  303. /* useful macros */
  304. #define BufByte(x) ((lpPCXStruct->pos < BUFSIZE) ? ((lpPCXStruct->buffer[lpPCXStruct->pos++] = x),OK) : putbuf(x,lpPCXStruct))
  305.   
  306. /* useful subfunctions */
  307. int putbuf(BYTE b,PCXStruct far *lpPCXStruct)
  308. {
  309.     if( _lwrite(lpPCXStruct->file,lpPCXStruct->buffer,BUFSIZE) != BUFSIZE ) return NODISK;
  310.     lpPCXStruct->buffer[0] = b; lpPCXStruct->pos = 1;
  311.     return OK;
  312. }
  313.   
  314. /************************************************************************/
  315. /************************************************************************/
  316. /************************************************************************/
  317. int FlushOutBuf(PCXStruct far *lpPCXStruct)
  318. {
  319.     if( !lpPCXStruct->pos ) return OK;
  320.     return ( _lwrite(lpPCXStruct->file,lpPCXStruct->buffer,lpPCXStruct->pos) != lpPCXStruct->pos ) ? NODISK : OK;
  321. }
  322.   
  323.   
  324. /************************************************************************/
  325. /************************************************************************/
  326. /************************************************************************/
  327. static int PCXpack(LPBYTE buf, WORD len, void far *lpPrivate)
  328. {
  329.     int PCXcount,ret;
  330.     BYTE PCXbyte;
  331.      PCXStruct far * lpPCXStruct = lpPrivate;
  332.   
  333.     PCXcount = 0;
  334.     while(len)
  335.     {
  336.         if(!PCXcount)
  337.         {
  338.             PCXcount = 1;
  339.             PCXbyte  = *buf++;
  340.             len --;
  341.         }
  342.         while(len && PCXcount < 0x3F && *buf == PCXbyte)
  343.         {
  344.             PCXcount++; buf++; len--;
  345.         }
  346.   
  347.         if(!len) /* return OK; */ break;
  348.   
  349.         if(PCXcount == 1 && (PCXbyte & 0xC0) != 0xC0 )
  350.         {
  351.             if(ret = BufByte(PCXbyte)) return ret;
  352.         }
  353.         else
  354.         {
  355.             if(ret = BufByte((BYTE)(PCXcount | 0xC0))) return ret;
  356.             if(ret = BufByte(PCXbyte)) return ret;
  357.         }
  358.   
  359.         PCXcount = 0;
  360.     }
  361.   
  362.     if(PCXcount)
  363.     {
  364.         if(PCXcount == 1 && (PCXbyte & 0xC0) != 0xC0 )
  365.         {
  366.             if(ret = BufByte(PCXbyte)) return ret;
  367.         }
  368.         else
  369.         {
  370.             if(ret = BufByte((BYTE)(PCXcount | 0xC0))) return ret;
  371.             if(ret = BufByte(PCXbyte)) return ret;
  372.         }
  373.         PCXcount = 0;
  374.     }
  375.     return OK;
  376. }
  377.   
  378. /************************************************************************\
  379.  *                                                                      *
  380.  * ROUTINE: int FAR PASCAL EndWrite(void far * lpPrivate)               *
  381.  *             void far * lpPrivate - pointer to                        *
  382.  *             custom structure to store private data                   *
  383.  *                                                                      *
  384.  * PURPOSE: Terminates conversion.                                      *
  385.  *                                                                      *
  386.  * RETURNS:                                                             *
  387.  * OK         - Success                                                 *
  388.  * BADFORMAT  - Bad signature                                           *
  389.  * UNSUPPORTED- Unsupported subformat                                   *
  390.  * BADFILE    - Error in file structure                                 *
  391.  * CANNOTOPEN - Cannot open src/dest                                    *
  392.  * INTERNAL   - Reserved                                                *
  393.  * BADDLL     - Error initializing DLL                                  *
  394.  * BADREQUEST - Unsupported type of conversion                          *
  395.  * BADTEMPFILE- Error creating/reading tempfile                         *
  396.  * NOMEMORY   - No enough global heap                                   *
  397.  * NODISK     - No enough disk space                                    *
  398.  * USERABORT  - Cancelled by user                                       *
  399.  * BADPARMS   - Conflicting parameters                                  *
  400.  *                                                                      *
  401. \************************************************************************/
  402. int FAR PASCAL EndWrite(void far *lpPrivate)
  403. {
  404.     WORD i;
  405.      PCXStruct far * lpPCXStruct = lpPrivate;
  406.   
  407.     if(lpPCXStruct->PCXpalette)
  408.     {
  409.         if(BufByte(0x0C)) return NODISK;
  410.         for(i = 0; i<256; i++)
  411.         {
  412.             if( BufByte(lpPCXStruct->pal[0][i]) ||
  413.                 BufByte(lpPCXStruct->pal[1][i]) ||
  414.                 BufByte(lpPCXStruct->pal[2][i]) ) return NODISK;
  415.         }
  416.     }
  417.     return FlushOutBuf(lpPCXStruct);
  418. }
  419.   
  420. /************************************************************************\
  421.  *                                                                      *
  422.  * ROUTINE: int FAR PASCAL WriteRow(int row, LPBYTE p,                  *
  423.  *                                           void far * lpPrivate)      *
  424.  *                                                                      *
  425.  * PURPOSE: Writes image row.                                           *
  426.  *                                                                      *
  427.  * PARAMETERS: int row - the number of row to read                      *
  428.  *             LPBYTE p - pointer to buffer to store image row          *
  429.  *             void far * lpPrivate - pointer to                        *
  430.  *             custom structure to store private data                   *
  431.  *                                                                      *
  432.  * RETURNS:                                                             *
  433.  * OK         - Success                                                 *
  434.  * BADFORMAT  - Bad signature                                           *
  435.  * UNSUPPORTED- Unsupported subformat                                   *
  436.  * BADFILE    - Error in file structure                                 *
  437.  * CANNOTOPEN - Cannot open src/dest                                    *
  438.  * INTERNAL   - Reserved                                                *
  439.  * BADDLL     - Error initializing DLL                                  *
  440.  * BADREQUEST - Unsupported type of conversion                          *
  441.  * BADTEMPFILE- Error creating/reading tempfile                         *
  442.  * NOMEMORY   - No enough global heap                                   *
  443.  * NODISK     - No enough disk space                                    *
  444.  * USERABORT  - Cancelled by user                                       *
  445.  * BADPARMS   - Conflicting parameters                                  *
  446.  *                                                                      *
  447. \************************************************************************/
  448. int FAR PASCAL WriteRow(int row,LPBYTE buf,void far *lpPrivate)
  449. {
  450.     int i;
  451.        PCXStruct far *lpPCXStruct = lpPrivate;
  452.  
  453.     for( i = 0; i < (int)lpPCXStruct->hdr.nplanes; i++ )
  454.     {
  455.         if( PCXpack(buf,lpPCXStruct->hdr.bplin,lpPrivate) ) return NODISK;
  456.         buf += lpPCXStruct->hdr.bplin;
  457.     }
  458.     return OK;
  459. }
  460.   
  461. /************************************************************************\
  462.  *                                                                      *
  463.  * ROUTINE: void FAR PASCAL CleanUp(void far *lpPrivate)                *
  464.  *             void far * lpPrivate - pointer to                        *
  465.  *             custom structure to store private data                   *
  466.  *                                                                      *
  467.  * PURPOSE: Frees all auxiliary buffers.                                *
  468.  *                                                                      *
  469. \************************************************************************/
  470. void FAR PASCAL CleanUp(void far *lpPrivate)
  471. {
  472. }
  473.  
  474.